/*
 * @Author: huangtianyang 916072572@qq.com
 * @Date: 2023-10-20 09:12:53
 * @LastEditors: huangtianyang
 * @LastEditTime: 2023-10-26 17:34:26
 * @FilePath: \cxl-h5\src\utils\index.ts
 */
import { refreshToken } from '@/apis/login'
import { vehicleLicenseIdentificationBase64 } from '@/apis/report'
import { CxlMessage } from '@/components/message'
import { storage } from '@/store/sessionStorage'
import { userStore } from '@/store/user.store'
import useWeixinSdk, { getBase64ImageSizeInKB } from './WXSdk'
import { businessLicense } from '@/apis/register'
import CompressImage from './compressImage'

export const isPC = () => {
    let result = true
    if (/Mobi|Android|iPhone/i.test(navigator.userAgent)) {
        // 当前设备是移动设备
        result = false
    }
    return result
}

/**
 * 时间戳转换成日期
 * @param timestamp
 * @returns
 */
export const timestampToTime = (timestamp: number) => {
    const date = new Date(timestamp * 1000) //时间戳为10位需*1000，时间戳为13位的话不需乘1000

    const Y = date.getFullYear() + '-'

    const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'

    const D = date.getDate() + ' '

    const h = date.getHours() + ':'

    const m = date.getMinutes() + ':'

    const s = date.getSeconds()

    return Y + M + D + h + m + s
}

/**
 * 验证输入的银行卡号
 * @param card
 * @returns
 */
export const regBankAccount = (card: string) => {
    return /^([1-9]{1})(\d{15}|\d{16}|\d{18})$/.test(card)
}

/**
 * 日期转时间戳
 * @param time
 * @returns
 */
export const timeToTimestamp = (time: string) => {
    const date = new Date(time)
    return date.getTime()
}

/**
 * 验证手机号码
 * @param mobile
 * @returns boolean
 */
export const regMobile = (mobile: string) => {
    return /^1[3456789]\d{9}$/.test(mobile)
}

/**
 * 验证座机号码
 */
export const checkSpecialPlane = (phone: string) => {
    //座机
    const phoneReg = !!phone.match(/^((0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/)
    const telReg = !!phone.match(/^1[3456789]\d{9}$/)
    console.log(phoneReg, telReg)
    if (phoneReg || telReg) {
        return true
    } else {
        return false
    }
}
/**
 * 验证邮箱
 * @param email
 * @returns
 */
export const checkEmail = (email: string) => {
    const reg = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/
    return reg.test(email)
}

//通过秒转换时间
export const timeFilterToSeconds = (seconds: number) => {
    let ss: number | string = parseInt(seconds.toString()) // 秒
    let mm: number | string = 0 // 分
    let hh: number | string = 0 // 小时
    if (ss > 60) {
        mm = Number(parseInt((ss / 60).toString()))
        ss = parseInt((ss % 60).toString())
    }
    if (mm > 60) {
        hh = parseInt((mm / 60).toString())
        mm = parseInt((mm % 60).toString())
    }
    let result = ('00' + parseInt(ss.toString())).slice(-2)
    if (mm > 0) {
        result = ('00' + parseInt(mm.toString())).slice(-2) + ' : ' + result
    } else {
        result = '00 : ' + result
    }
    if (hh > 0) {
        result = ('00' + parseInt(hh.toString())).slice(-2) + ': ' + result
    }
    return result
}

//将天数转换成年月日
export const calculateTimimg = (d: number) => {
    let months = 0,
        years = 0,
        days = 0
    while (d) {
        if (d >= 365) {
            years++
            d -= 365
        } else if (d >= 30) {
            months++
            d -= 30
        } else {
            days++
            d--
        }
    }
    return years + '年' + months + '月' + days + '日'
}

//设置支付倒计时
export class PaySetInterval {
    //定时器
    timer: null | number | undefined | NodeJS.Timer
    //15分钟倒计时 秒
    expireTime = 0
    //初始时间
    startTime = 0
    //当前时间
    currentTime = 0
    //second 秒
    constructor(eTime: number, sTime: number) {
        this.expireTime = eTime
        this.startTime = sTime
        this.currentTime = new Date().getTime()
    }
    start(update = (arg?: any) => {}, callback = () => {}) {
        this.stop()
        let s = (this.expireTime - this.currentTime) / 1000
        let t = timeFilterToSeconds(s)
        console.log('s', s, 't', t, this.startTime, this.expireTime, this.currentTime, Math.floor(s))
        if (s < 0) {
            this.stop(callback)
            return
        }
        update(t)
        this.timer = setInterval(() => {
            if (Math.floor(s) < 0) {
                this.stop(callback)
            } else {
                this.currentTime = new Date().getTime()
                s = (this.expireTime - this.currentTime) / 1000
                t = timeFilterToSeconds(s)
                // console.log('s', s, 't', t)
                update(t)
            }
        }, 1000)
    }
    stop(callback = () => {}) {
        if (this.timer) {
            clearInterval(this.timer)
            callback()
        }
    }
}

//设置倒计时
export class CountDown {
    //定时器
    timer: null | number | undefined | NodeJS.Timer

    second = 0

    //second 秒
    constructor(second: number) {
        // console.log('second', second)
        this.second = second
        clearInterval(storage.get('countDownTimer'))
    }
    start(update = (arg?: number) => {}, callback = () => {}) {
        this.stop()
        let n = this.second
        this.timer = setInterval(() => {
            n--
            if (n < 1) {
                this.stop(callback)
            } else {
                console.log(`${this.second}倒计时`, n)
                update(n)
            }
        }, 1000)
        storage.set('countDownTimer', this.timer.toString())
    }
    stop(callback = () => {}) {
        if (this.timer) {
            clearInterval(this.timer)
            callback()
        }
    }
}

/**
 * 获取链接的参数
 * @param variable
 * @returns
 */
export const getQueryVariable = (variable: string) => {
    const query: string = window.location.search.substring(1)
    const vars: string[] = query.split('&')
    for (let i = 0; i < vars.length; i++) {
        const pair = vars[i].split('=')
        if (pair[0] == variable) {
            return pair[1]
        }
    }
}

/**
 * 保持登录倒计时
 */
export class KeepLoginCountDown {
    //定时器
    timer: null | number | undefined | NodeJS.Timer

    //当前时间
    currentTime = 0

    //截至时间
    endTime = 0

    //当前时间距离截至时间
    intervalTime = 0

    //用户登录时间
    userLoginTime = 0

    second = 0

    loginStatus = false

    //second 秒
    constructor(second: number) {
        console.log('second', second)
        this.second = second
        this.currentTime = new Date().getTime()
        //获取登录时间
        this.userLoginTime = Number(storage.get('loginTime'))
        /**
         * 从登录时间开始计算 倒计时 second分钟
         *
         * 1、创建登录时间对象
         * const loginDate = new Date(this.userLoginTime)
         * 2、通过loginDate得到分钟
         * const loginMinute = loginDate.getMinutes()
         * 3、
         * const endMinute = loginMinute + second
         * 4、
         * const e = loginDate.setMinutes(endMinute)
         * 5、再new Date()
         * const endDate = new Date(e)
         * 6、调用
         * this.endTime = endDate.getTime()
         */

        const loginDate = new Date(this.userLoginTime)
        //Date.setMinutes(min, sec, millisec) min必需。表示分钟的整数。
        // this.endTime = new Date(loginDate.setMinutes(loginDate.getMinutes() + Math.round(this.minute))).getTime()
        this.endTime = new Date(loginDate.setSeconds(loginDate.getSeconds() + Math.round(this.second))).getTime()

        console.log(
            second,
            '登录时间',
            this.userLoginTime,
            '当前时间',
            this.currentTime,
            '已登录',
            timeFilterToSeconds((this.currentTime - this.userLoginTime) / 1000),
            '截至时间',
            this.endTime
        )

        clearInterval(storage.get('loginCountDownTimer'))
    }
    start(callback = () => {}) {
        this.stop()
        let s = 0
        this.currentTime = new Date().getTime()

        this.intervalTime = this.endTime - this.currentTime // 两个时间戳相隔的毫秒数
        s = parseInt((this.intervalTime / 1000).toString()) //得到 秒

        //保持登录状态时，默认登录
        if (s > 0) {
            if (!this.loginStatus) {
                //设置
                storage.set('loginStatus', 'true')
                userStore().loginStatus = true
            }
        }

        this.timer = setInterval(() => {
            this.currentTime = new Date().getTime()

            this.intervalTime = this.endTime - this.currentTime // 两个时间戳相隔的毫秒数
            // console.log('time 秒', this.intervalTime)
            s = parseInt((this.intervalTime / 1000).toString()) //得到 秒
            if (s > 0) {
                // console.log('time 秒', s)
            } else if (s < 0) {
                console.log('relogin 2')
                storage.set('keepLoginStatus', 'false')
                this.stop(callback)
            } else {
                // console.log('time', s)
                /**
                 * 倒计时结束
                 * 设置保持登录状态结束，下次进入就必须输入密码，重新登录
                 */
                storage.set('keepLoginStatus', 'false')
                this.stop(callback)

                refreshToken().then(e => {
                    const expireTime: number = Number(e.data.data.expire) - 5
                    storage.set('token', e.data.data.accessToken)
                    storage.set('refreshToken', e.data.data.refreshToken)
                    //保留首次登录的时间
                    storage.set('loginTime', new Date().getTime().toString())
                    //保持登录过期时间expire 秒
                    storage.set('expire', '' + expireTime)
                    //设置保持登录状态
                    storage.set('keepLoginStatus', 'true')
                    storage.set('loginStatus', 'true')

                    new KeepLoginCountDown(Number(expireTime) / 1).start()
                })
            }
        }, 1000)

        storage.set('loginCountDownTimer', this.timer.toString())
    }
    stop(callback = () => {}) {
        if (this.timer) {
            clearInterval(this.timer)
            callback()
        }
    }
}

/**
 * 调用wxsdk上传图片
 * @param succeed
 */
export const uploadImage = ({
    start = () => {},
    succeed = (localData: any, result: any) => {},
    failed = () => {},
    vehicleLicense = false,
    base64 = ''
}) => {
    if (isPC()) {
        start()
        console.log('图片大小', getBase64ImageSizeInKB(base64).toFixed(1))
        if (getBase64ImageSizeInKB(base64) >= 3 * 1024) {
            // CxlMessage.error('图片大小限制在4M以内，请重新上传！')
            const CI = new CompressImage()
            CI.init(base64, (str: string) => {
                uploadData(str, vehicleLicense, succeed, failed)
            })
        } else {
            uploadData(base64, vehicleLicense, succeed, failed)
        }
    } else {
        useWeixinSdk.onChooseImage().then((res: any) => {
            start()

            let base64 = res.localData
            if (res.localData.indexOf('data:image') != 0) {
                //判断是否有这样的头部，因为安卓返回的是没有带头部的，所以要判断给它加上
                base64 = 'data:image/jpeg;base64,' + res.localData
            }
            console.log('图片大小', getBase64ImageSizeInKB(base64).toFixed(1))
            if (getBase64ImageSizeInKB(base64) >= 3 * 1024) {
                // CxlMessage.error('图片大小限制在3M以内，请重新上传！')
                const CI = new CompressImage()
                CI.init(base64, (str: string) => {
                    console.log('CompressImage', str)
                    uploadData(str, vehicleLicense, succeed, failed)
                })
            } else {
                uploadData(res.localData, vehicleLicense, succeed, failed)
            }
        })
    }
}

const uploadData = (
    localData: string,
    vehicleLicense = false,
    succeed = (base64: any, result: any) => {},
    failed = () => {}
) => {
    let base64 = localData
    if (localData === '') {
        return
    }

    if (base64.indexOf('data:image') != 0) {
        //判断是否有这样的头部，因为安卓返回的是没有带头部的，所以要判断给它加上
        base64 = 'data:image/jpeg;base64,' + base64
    }
    if (vehicleLicense) {
        //查询报告上传行驶证
        const formData = new FormData()
        formData.append('file', base64.split('base64,')[1])

        vehicleLicenseIdentificationBase64(formData).then(
            result => {
                if (result.data.value == 200) {
                    console.log('imgUrl', result.data.data.url)
                    succeed(base64, result)
                } else {
                    failed()
                    CxlMessage.error({ content: '行驶证解析失败，请重新上传！' })
                }
            },
            err => {
                failed()
            }
        )
    } else {
        //注册时上传营业执照

        // uploadFileBase64(base64.split('base64,')[1]).then(
        //     result => {
        //         if (result.data.value == 200) {
        //             console.log('imgUrl', result.data.data.url)
        //             succeed(base64, result)
        //         } else {
        //             failed()
        //             CxlMessage.error('图片上传失败！')
        //         }
        //     },
        //     err => {
        //         failed()
        //     }
        // )
        const formData = new FormData()
        formData.append('file', base64.split('base64,')[1])
        businessLicense(formData).then(
            result => {
                if (result.data.value == 200) {
                    console.log('imgUrl', result.data.data.url)
                    succeed(base64, result)
                } else if (result.data.value === 60001) {
                    failed()
                    CxlMessage.error({ content: '解析失败请重新上传！' })
                } else {
                    failed()
                    CxlMessage.error({ content: '图片上传失败！' })
                }
            },
            () => {
                failed()
            }
        )
    }
}

/**
 * 校验输入的密码，至少8位，包含数字+字母
 * @param password
 */
export const checkPassword = (password: string) => {
    let result = false
    if (password == '' || password == null || password.length < 8) {
        result = false
        return false
    }
    const reg = new RegExp(/^(?![^a-zA-Z]+$)(?!\D+$)/)
    if (reg.test(password)) {
        result = true
    }
    return result
}

//判断是否是ios
export const isIOS = () => {
    const userAgent = navigator.userAgent
    return !!userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
}

// 判断统一社会信用代码  (正确示例)9135052155323005XL
export function CheckSocialCreditCode(Code: string) {
    const patrn = /^[0-9A-Z]+$/ // 18位校验及大写校验
    if (Code.length !== 18 || patrn.test(Code) === false) {
        return false
    } else {
        let Ancode // 统一社会信用代码的每一个值
        let Ancodevalue // 统一社会信用代码每一个值的权重
        let total = 0
        const weightedfactors = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28] // 加权因子
        const str = '0123456789ABCDEFGHJKLMNPQRTUWXY' // 不用I、O、S、V、Z
        for (let i = 0; i < Code.length - 1; i++) {
            Ancode = Code.substring(i, i + 1)
            Ancodevalue = str.indexOf(Ancode)
            total = total + Ancodevalue * weightedfactors[i] // 权重与加权因子相乘之和
        }
        let logiccheckcode: number | string = 31 - (total % 31)
        if (logiccheckcode === 31) {
            logiccheckcode = 0
        }
        const Str = '0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y'
        const Array_Str = Str.split(',')
        logiccheckcode = Array_Str[logiccheckcode]
        const checkcode = Code.substring(17, 18)
        console.log('logiccheckcode', logiccheckcode, 'checkcode', checkcode)
        if (logiccheckcode !== checkcode) {
            return false
        }
        return true
    }
}

// const debouncedUse: Function = new Debounced().use(this.request, 1000)
// const throttle = new Throttle()
// const throttleUse: Function = this.throttle.use(this.request, 1000)

// 防抖(ts)
export class Debounced {
    /**
     * @param func 需要包装的函数
     * @param delay 延迟时间，单位ms
     * @param immediate 是否默认执行一次(第一次不延迟)
     */
    public use = (func = () => {}, delay: number, immediate = false): any => {
        let timer: NodeJS.Timeout
        return (...args: any) => {
            if (immediate) {
                func.apply(this, args) // 确保引用函数的指向正确，并且函数的参数也不变
                immediate = false
                return
            }
            clearTimeout(timer)
            timer = setTimeout(() => {
                func.apply(this, args)
            }, delay)
        }
    }
}

// 节流(ts)
export class Throttle {
    private timer: NodeJS.Timeout | string = ''
    private stop = false
    private death = false
    /**
     * @param func 需要包装的函数
     * @param delay 延迟时间，单位ms
     * @param immediate 是否默认执行一次(第一次不延迟)
     */
    public use(func = () => {}, delay: number, immediate = false): any {
        let flag = true
        return (...args: any) => {
            if (this.death) {
                func.apply(this, args)
                return
            }
            if (this.stop) {
                func.apply(this, args)
                return
            }
            if (immediate) {
                func.apply(this, args)
                immediate = false
                return
            }
            if (!flag) {
                return
            }
            flag = false
            this.timer = setTimeout(() => {
                func.apply(this, args)
                flag = true
            }, delay)
        }
    }

    // 销毁
    public destroy() {
        this.death = true
        this.stop = true
        if (this.timer) {
            clearTimeout(this.timer)
            this.timer = ''
        }
    }
    // 开启
    public open() {
        if (!this.death) {
            this.stop = false
        }
    }
    // 关闭
    public close() {
        this.stop = true
    }
}

export const checkTax = (obj: string) => {
    if (/^[A-Z0-9]{15}$|^[A-Z0-9]{17}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/.test(obj)) {
        return true
    } else {
        return false
    }
}

// 动态修改页面标题
export const editPageTitle = (name: string) => {
    document.title = name
    const i = document.createElement('iframe')
    i.src = '/favicon.ico'
    i.style.display = 'none'
    i.onload = function () {
        setTimeout(function () {
            i.remove()
        }, 10)
    }
    document.body.appendChild(i)
}

//将天数转换成年月日
export const dayToDate = (n: number) => {
    //年 365
    //月 31
    //日 1
    const years = Math.floor(n / 365)
    const months = Math.floor((n % 365) / 31)
    const days = (n % 365) % 31

    return years + '年' + months + '月' + days + '天'
}
